嗨,昨天說明了如何設定Scrapy-splash
爬取動態網頁,包含透過docker
啟動Splash
來幫助渲染Js
,以及Scpray
內 Middlewares
的設定,今天我們會以來實際操做一次如何使用,至於設定的詳情,請見昨天的文章,那我們就開始吧!
今天我們要爬的範例網站為 http://quotes.toscrape.com/js/
首先,來看網頁的內容(如下圖),假設我們今天要抓的是文字,可以看到它在<div class="quote"></div>
內的<span class="text"></span>
。
可以來撰寫程式了,在spider/
內新增一個spider
程式碼:
import scrapy
from bs4 import BeautifulSoup
class NewsSpider(scrapy.Spider):
name = "quotesjs"
start_urls = ['http://quotes.toscrape.com/js/']
def parse(self, response):
soup = BeautifulSoup(response.text, 'lxml')
quotes = soup.select('div.quote span.text')
for q in quotes:
print(q.text)
執行後會發現我們沒抓到任何的內容,這是因為裡面的文字是透過js渲染的,所以我們現在來更改程式碼,為了測試是否有爬到文字,所以我們重寫了start_requests()
的內容,將start_urls
裡的連結透過SplashRequest
送到parse
的function,在parse
內解析網頁內容,而這個部分我沒有做變更,如下程式碼:
import scrapy
from bs4 import BeautifulSoup
from scrapy_splash import SplashRequest
class NewsSpider(scrapy.Spider):
name = "quotesjs"
start_urls = ['http://quotes.toscrape.com/js/']
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(url, self.parse, args={'wait': 0.5})
def parse(self, response):
soup = BeautifulSoup(response.text, 'lxml')
quotes = soup.select('div.quote span.text')
for q in quotes:
print(q.text)
執行結果:
上面可以看到[scrapy.core.engine] DEBUG: Crawled (200) <GET http://quotes.toscrape.com/js/ via http://localhost:8050/render.html>
表示我們有透過Splash
渲染內容,因此可以看到下面為爬到的文字,表示成功了。
但是這樣只有爬到一頁而已,如果我們要切頁怎麼做呢?很簡單只要取得它的href
,我們先來看下一頁
的內容:
可以看到它就在<li class="next"></i>
內的<a>
內,為什麼不直接抓<a>
是因為<a>
可能有很多個,但在<li class="next"></i>
的只有這一個,理解以後我們只需要新增幾行程式碼在parse
下面:
print('------------------------------------')
next_page_href = soup.select_one('li.next a').get('href')
next_url = 'http://quotes.toscrape.com' + next_page_href
yield SplashRequest(next_url, self.parse, args={'wait': 0.5})
print()
只是用來區隔不同頁用的next_page_href
為<a>
內的href
內容,取到後我們接起來變成next_url
下一頁的url
,再透過SplashRequest
的callback去做。執行後就可以看到下圖,我們爬到了多頁的內容,透過--
分隔開:
好的,接續昨天的主題,今天用一個簡單的範例網站說明了如何使用Splash
爬取動態的網站。
最近真的忙到焦頭爛額(暈)
上週末跑高雄兩天、這週期中考、拜六要跑臺北,學校還有很多事務在趕(現在是在抱怨嗎?)
所以如果有誤的話還請多包涵(歡迎回覆糾正錯字了!),不過這幾天是寫範例應該比較不會有誤吧我覺得,畢竟都有自己再重寫過程式碼測試一次,總之就是默默的也第22
天了,不管有沒有人看都會盡力的完成這最後幾天的(鞠躬)。
那就明天見了!